package core;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.ArrayList;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

public class Aes {

	
	public static List<Integer> padText(String text){
		text = "<mxit/>" + text;
		
		//get unicode codepoints
		List<Integer> data = getCodePoints(text);
		
		//add padding
		int pads = 16 - (data.size() %16);
		for(int i=0;i<pads-1;i++) {
			data.add(0);
		}
		data.add(pads);
		
		return data;
	}
		
	public static List<Integer> padKey(String key) {
		List<Integer> keyCodePoints = getCodePoints(key);
		String ksmask ="6170383452343567";
		List<Integer> ksmaskCodePoints = getCodePoints(ksmask);
		
		for(int i = 0; i<keyCodePoints.size();i++) {
			ksmaskCodePoints.add(i, keyCodePoints.get(i));
		}
		return ksmaskCodePoints;

	}
	
	public static List<Integer> encrypt(String keystring,String textstring) {
		List<Integer> key = padKey(keystring);
		List<Integer> text = padText(textstring);
		
		Cipher cipher = null;
		try {
			cipher = Cipher.getInstance("AES");
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//make byte array key
		byte[] bkey =new byte[key.size()];
		for(int i= 0; i< key.size();i++) {
			bkey[i] = (byte)key.get(i).intValue();
		}
		byte[] bdata = new byte[text.size()];
		for(int i= 0; i< text.size();i++) {
			bdata[i] = (byte)text.get(i).intValue();
		}
		SecretKeySpec skeySpec = new SecretKeySpec(bkey,"AES");
		try {
			cipher.init(Cipher.DECRYPT_MODE, skeySpec);
		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		byte[] encoded = null;
		try {
			encoded = cipher.doFinal(bdata);
		} catch (IllegalBlockSizeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (BadPaddingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		List<Integer> result = new ArrayList<Integer>();
		for(byte b:encoded) {
			result.add(new Integer(b));
		}
		return result;
	}
	
	public static List<List<Integer>> split(List<Integer> text,int chunkSize) {
		List<List<Integer>> parts = new ArrayList<List<Integer>>();
		
		List<Integer> part = new ArrayList<Integer>();
		for(Integer i:text) {
			if(part.size()==chunkSize) {
				parts.add(part);
				part = new ArrayList<Integer>();
			}
			part.add(i);
		}
		parts.add(part);
		return parts;
	}
	public static List<Integer> getCodePoints(String text) {
		
		List<Integer> data = new ArrayList<Integer>();
		for(Character c:text.toCharArray()){
			data.add((int)c);
		}
		return data;
	}
	
}
